<template>
  <div class="item-box">
    <div class="item-list" v-for="(group, mindex) in group1" :key="mindex" v-show="mindex < maxLevel">
      <!-- <div class="num">{{ mindex + 1 }}级</div> -->
      <vue-draggable-next v-model="group1[mindex]" handle=".move" animation="150" @end="dragEnd(mindex)">
        <div
          class="item"
          v-for="(item, index) in group"
          :key="index"
          @click="setItem(mindex, index)"
          :class="{ active: active[mindex] === index }"
        >
          <i class="MC_iconfont MC_icon-tuodong-shu move" style="float: left; cursor: move"></i>
          <el-input
            v-model="item.value"
            placeholder="请输入选项"
            :maxlength="50"
            @change="itemChange($event, mindex, index)"
          ></el-input>
          <div class="operate">
            <i class="MC_iconfont MC_icon-shanchu2-xian" @click.stop="remove(mindex, index)"></i>
          </div>
        </div>
      </vue-draggable-next>
      <div @click="add(mindex)" class="add-btn"><i class="MC_iconfont MC_icon-tianjia-xian" />添加选项</div>
    </div>
  </div>
</template>

<script lang="ts">
/**
 * 级联选择器
 * 设置数据 setData(data:初始数据数组格式，level：层级)
 * 获取数据 getData 会对空值数据进行过滤
 */
import { defineComponent, reactive, toRefs, watch } from 'vue'
import { VueDraggableNext } from 'vue-draggable-next'
import { v4 as uuidv4 } from 'uuid'
import { deepClone } from '@/common/utils/common'
import { ElMessage } from 'element-plus'
export default defineComponent({
  name: 'CascaderCom',
  components: { VueDraggableNext },
  props: {
    isSave: {
      type: Boolean,
      default: false
    }
  },
  setup(props, { emit }) {
    const STATE: any = reactive({
      group1: [[], [], [], [], []], // 五个数组保存不同层级的数据
      active: [-1, -1, -1, -1, -1], // 当前各个层级选中的index
      maxLevel: 2, //最大层级 默认两级
      index: 0 // 当前层级点击的index
    })

    // 初始化数据
    const setData = (data: any) => {
      STATE.group1[0] = data.children
      STATE.maxLevel = data.level
      for (let i = 0; i < data.level; i++) {
        // 编辑默认展示
        setItem(i, 0)
      }
    }

    // 选项去重
    const itemChange = (val: string | number, mindex: number, index: number) => {
      STATE.group1[mindex].map((v: any, i: number) => {
        if (i !== index && val === v.value) {
          setTimeout(() => {
            // 防止input框不失去焦点直接点保存 两个提示
            if (!props.isSave) {
              ElMessage.error('选项已存在')
            }
          }, 500)
          STATE.group1[mindex][index].value = ''
        }
      })
    }

    // 设置层级
    const setLevel = (level: number) => {
      if (level >= STATE.maxLevel) {
        STATE.maxLevel = level
      } else {
        STATE.maxLevel = level
        const newData = JSON.parse(JSON.stringify(STATE.group1[0]))
        newData.map((v: any) => {
          filterData(v, 1)
        })
        setData({
          children: newData,
          level
        })
        STATE.active[level - 1] = -1
        for (let i = level; i < 5; i++) {
          STATE.active[i] = -1
          STATE.group1[i] = []
        }
      }
    }

    // 层级改变时需要清除之前得数据
    const filterData = (data: any, level: number) => {
      if (level === STATE.maxLevel) {
        data.children = null
      } else if (data.children) {
        data.children.map((v: any) => {
          filterData(v, level + 1)
        })
      }
    }

    // 删除数据，如果删除的是当前选中的，需要处理下一层级数据
    const remove = (mindex: number, index: number) => {
      STATE.group1[mindex].splice(index, 1)
      if (index === STATE.active[mindex]) {
        STATE.active[mindex] = -1
        for (let i = mindex + 1; i < STATE.maxLevel; i++) {
          STATE.active[i] = -1
          STATE.group1[i] = []
        }
      }
    }

    // 添加数据
    const add = (mindex: number) => {
      STATE.group1[mindex].push({
        value: '',
        key: uuidv4().replace(/-/g, '')
      })
    }

    // 设置当前选中数据
    const setItem = (mindex: number, index: number) => {
      // mindex---层级的key  index---当前层级选中的key
      if (mindex < STATE.maxLevel - 1) {
        STATE.active[mindex] = index // 当前层级选中的index
        for (let i = mindex + 1; i < STATE.maxLevel; i++) {
          STATE.active[i] = -1
          STATE.group1[i] = []
        }
        if (!(STATE.group1[mindex] && STATE.group1[mindex][index] && STATE.group1[mindex][index].children)) {
          STATE.group1[mindex][index].children = []
        }
        // 选中的下一级展示选中层级的children
        STATE.group1[mindex + 1] = STATE.group1[mindex][index].children
      }
    }

    const dragEnd = (mindex: number) => {
      setItem(mindex, STATE.active[mindex]) // 拖拽结束后active的children更新
      if (mindex - 1 >= 0) {
        // 更新group1[0]的数据为拖拽后的数据---预览的数据为拖拽后的数据
        STATE.group1[mindex - 1][STATE.active[mindex - 1]].children = STATE.group1[mindex]
      }
    }

    // 获取数据
    const getData = () => {
      return removeLoop(deepClone(STATE.group1[0] ? STATE.group1[0] : []))
    }

    const removeEmpty = (data: any) => {
      const newData: any = []
      data.map((v: any) => {
        if (v.value !== '') {
          newData.push(v)
        }
      })
      return newData
    }

    // 过滤name为空的数据
    const removeLoop = (inData: any) => {
      inData.map((v: any) => {
        if (v.children && v.children.length > 0) {
          v.children = removeEmpty(v.children)
          removeLoop(v.children)
        } else {
          v.children = null
        }
      })
      return {
        children: inData,
        level: STATE.maxLevel
      }
    }

    watch(
      () => STATE.group1,
      () => {
        emit('onItemChange', getData())
      },
      { deep: true }
    )

    return {
      ...toRefs(STATE),
      setData,
      setLevel,
      remove,
      add,
      setItem,
      dragEnd,
      getData,
      itemChange
    }
  }
})
</script>

<style lang="stylus" scoped>
.item-box
  overflow auto
  white-space nowrap
  display flex
  .item-list
    background var(--mc-gray1-color)
    width 200px
    border-radius 4px
    overflow hidden
    flex 1 0 auto
    flex-basis 200px
    margin-right 8px
    padding 8px 0
    display inline-block
    .active
      color #008cee
      background #e5f3fd
    .MC_iconfont
      color rgba(0, 0, 0, 0.38)
    .add-btn
      cursor pointer
      color var(--mc-main-color)
      margin-left 20px
      .MC_icon-tianjia-xian
        color var(--mc-main-color)
        margin-right 6px
    .num
      border-bottom 1px solid #E7E9ED
      padding 0 15px
      color #303753
    .item
      line-height 32px
      padding 8px 16px
      cursor pointer
      overflow hidden
      .el-input
        width 120px
        float left
        overflow hidden
        text-overflow ellipsis
        white-space nowrap
        margin-left 10px
      .operate
        float right
        line-height 32px
        i
          color rgba(0, 0, 0, 0.38)
          cursor pointer
          &:hover
            color #fc6c5c
</style>
